//
//  M3Subject.m
// 
//
//  Created by xm on 2023/8/31.
//

#import "M3Subject.h"

@interface M3Subject()

@property(nonatomic, strong) XMLogger *logger;

@end


@implementation M3Subject



-(instancetype) init
{
    if(self = [super init]){
        
    }
    return self;
}


#pragma mark - getter


- (XMLogger *)logger
{
    if(!_logger){
        _logger = [XMLogger loggerWithScopeName:NSStringFromClass(self.class)];
    }
    
    return _logger;
}

- (NSMutableArray<M3Subscription *> *)subscriptions
{
    if(!_subscriptions){
        _subscriptions = [NSMutableArray array];
    }
    return  _subscriptions;
}

- (NSMutableArray<M3Subscription *> *)disposableSubscriptions
{
    if(!_disposableSubscriptions){
        _disposableSubscriptions = [NSMutableArray array];
    }
    return  _disposableSubscriptions;
}

#pragma mark - methods



-(void)notify:(NSInteger)code paylod:(nullable id)payload
{
    __block NSDictionary * _payload = payload;
    
    [self.subscriptions enumerateObjectsUsingBlock:^(M3Subscription * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if(code == obj.code){
//            isLog = YES;
        }

 
        if(obj.caller == nil){
            return;
        }
        if(obj.code == code){
    
            obj.block(_payload);
        }
    }];
    
    
    [self.disposableSubscriptions enumerateObjectsUsingBlock:^(M3Subscription * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if(code == obj.code){
//            isLog = YES;
        }
   
        if(obj.caller == nil){
            return;
        }
        if(obj.code == code){
        
            obj.block(_payload);
            obj.caller = nil;
        }
  
    }];

}



-(M3Subscription*) subscribeCode:(NSInteger) code caller:(id) caller block:(M3SubscriptionBlock) block
{
//    __weak __typeof(caller) _caller = caller;
    M3Subscription * subscription = [M3Subscription subscriptionWithCaller:caller code:code block:block];
    [self.subscriptions addObject:subscription];
    
//    self.logger.log(@"XXX-3 self:%@ caller:%@ code:%ld subscriptions.count:%ld", self, caller, code, self.subscriptions.count);

    return subscription;
}

-(M3Subscription*) subscribeOnceCode:(NSInteger) code caller:(id) caller block:(M3SubscriptionBlock) block
{
//    __weak __typeof(caller) _caller = caller;
    M3Subscription * subscription = [M3Subscription subscriptionWithCaller:caller code:code block:block];
    [self.disposableSubscriptions addObject:subscription];
//    self.logger.log(@"XXX-4 self:%@ caller:%@ code:%ld subscriptions.count:%ld", self, caller, code, self.disposableSubscriptions.count);

    return subscription;
}

-(BOOL) isHaveSubscribed:(id) caller cdoe:(NSInteger) code
{
    __block BOOL isExist = NO;
    [self.subscriptions enumerateObjectsUsingBlock:^(M3Subscription * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if(obj.caller == caller && obj.code == code){
            isExist = YES;
        }
    }];
    
    return isExist;
}

@end
